import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:mock_douban/service/http_config.dart';

/// HTTP 请求异常
class HttpException implements Exception {
  final int? code;
  final String? message;
  final dynamic data;

  HttpException({this.code, this.message, this.data});

  @override
  String toString() {
    return 'HttpException: code=$code, message=$message, data=$data';
  }
}

/// HTTP 请求封装类
class HttpRequest {
  // 单例实例
  static final HttpRequest _instance = HttpRequest._internal();

  // Dio 实例
  late Dio _dio;

  // 私有构造函数
  HttpRequest._internal() {
    _initDio();
  }

  // 获取单例
  factory HttpRequest.getInstance() => _instance;

  // 初始化 Dio
  void _initDio() {
    BaseOptions options = BaseOptions(
      baseUrl: HttpConfig.baseUrl, // 基础URL
      connectTimeout: const Duration(seconds: 100), // 连接超时
      receiveTimeout: const Duration(seconds: 100), // 接收超时
      sendTimeout: const Duration(seconds: 100), // 发送超时
      responseType: ResponseType.json, // 响应类型
      validateStatus: (int? status) {
        // 自定义状态码验证
        return status != null && status >= 200 && status < 300;
      },
    );

    _dio = Dio(options);

    // 设置默认请求头
    _dio.options.headers.addAll({
      'Content-Type': 'application/json',
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0',
    });

    // 添加拦截器
    _dio.interceptors.addAll([
      // 日志拦截器（仅在调试模式下打印）
      if (kDebugMode)
        InterceptorsWrapper(
          onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
            print('请求URL: ${options.uri}');
            print('请求头: ${options.headers}');
            print('请求参数: ${options.data ?? options.queryParameters}');
            return handler.next(options);
          },
          onResponse: (Response response, ResponseInterceptorHandler handler) {
            print('响应数据: ${response.data}');
            return handler.next(response);
          },
          onError: (DioError error, ErrorInterceptorHandler handler) {
            print('请求错误: $error');
            return handler.next(error);
          },
        ),
      // 其他拦截器...
    ]);
  }

  /// GET 请求
  Future<T> get<T>(
      String path, {
        Map<String, dynamic>? queryParameters,
        Options? options,
      }) async {
    try {
      Response response = await _dio.get(
        path,
        queryParameters: queryParameters,
        options: options,
      );
      return _handleResponse<T>(response);
    } on DioError catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  /// POST 请求
  Future<T> post<T>(
      String path, {
        dynamic data,
        Map<String, dynamic>? queryParameters,
        Options? options,
      }) async {
    try {
      Response response = await _dio.post(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
      );
      return _handleResponse<T>(response);
    } on DioError catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  /// PUT 请求
  Future<T> put<T>(
      String path, {
        dynamic data,
        Map<String, dynamic>? queryParameters,
        Options? options,
      }) async {
    try {
      Response response = await _dio.put(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
      );
      return _handleResponse<T>(response);
    } on DioError catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  /// DELETE 请求
  Future<T> delete<T>(
      String path, {
        dynamic data,
        Map<String, dynamic>? queryParameters,
        Options? options,
      }) async {
    try {
      Response response = await _dio.delete(
        path,
        data: data,
        queryParameters: queryParameters,
        options: options,
      );
      return _handleResponse<T>(response);
    } on DioError catch (e) {
      _handleError(e);
      rethrow;
    }
  }

  /// 处理响应数据
  T _handleResponse<T>(Response response) {
    // 如果响应数据是 Map 或 List，尝试解析为 T 类型
    if (response.data is Map || response.data is List) {
      return response.data as T;
    }

    // 如果 T 是 String，直接返回字符串
    if (T == String) {
      return response.toString() as T;
    }

    // 其他情况，尝试转换为 T 类型
    try {
      return response.data as T;
    } catch (e) {
      throw HttpException(
        code: response.statusCode,
        message: '解析响应数据失败',
        data: response.data,
      );
    }
  }

  /// 处理错误
  void _handleError(DioError error) {
    String? errorMessage;
    int? errorCode;

    if (error.response != null) {
      // 服务器返回的错误
      errorCode = error.response?.statusCode;
      try {
        // 尝试从响应数据中获取错误信息
        final data = error.response?.data;
        if (data is Map<String, dynamic>) {
          errorMessage = data['message'] ?? data['msg'] ?? '未知错误';
        } else {
          errorMessage = error.response?.statusMessage ?? '请求失败';
        }
      } catch (e) {
        errorMessage = '解析错误信息失败';
      }
    } else {
      errorMessage = error.message;
    }

    throw HttpException(
      code: errorCode,
      message: errorMessage,
      data: error.response?.data,
    );
  }

  /// 添加拦截器
  void addInterceptor(Interceptor interceptor) {
    _dio.interceptors.add(interceptor);
  }

  /// 清除所有拦截器
  void clearInterceptors() {
    _dio.interceptors.clear();
    _initDio(); // 重新初始化，添加默认拦截器
  }

  /// 设置全局 headers
  void setHeaders(Map<String, dynamic> headers) {
    _dio.options.headers.addAll(headers);
  }

  /// 设置基础 URL
  void setBaseUrl(String baseUrl) {
    _dio.options.baseUrl = baseUrl;
  }
}